"""
Case Type   : Interface
Case Name   : PQconnectdbParams():键值对方式测试-登录不存在的数据库
Create At   : 2025/2/20
Owner       : wan005
Description :
    1.解压libpq压缩包
    2.将pqconnectdbparams_key.c 文件复制到对应路径下，连接数据库的相关信息写入文件
    3.编译脚本
    4.执行脚本，连接不存在的数据库
Expect      :
    1.解压完成
    2.写入文件成功
    3.编译成功
    4.连接失败
History     :
"""
import os
import unittest
import sys
from yat.test import Node
from yat.test import macro
from testcase.utils.Common import Common
from testcase.utils.ComInstall import LiteInstall, LiteUnInstall
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger


class Lite(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'---{os.path.basename(sys.argv[4])} start---')
        self.pkg_path = os.path.dirname(macro.DB_SCRIPT_PATH)
        self.com_install = LiteInstall(self.pkg_path, None, None)
        self.com_uninstall = LiteUnInstall(self.pkg_path)
        self.root_node = Node('PrimaryRoot')
        self.user_node = Node('PrimaryDbUser')
        self.common = Common()
        self.constant = Constant()
        self.params_file = 'PQconnectdbParams_key'
        self.com_user = 'u_connection_002'
    
    def test_connection(self):
        text = '----prestep1:获取可用用户和端口;expect:获取成功----'
        self.log.info(text)
        self.user, self.port = self.com_install.get_user_and_port(
            self.root_node)
        self.log.info(f'self.user:{self.user}, self.port:{self.port}')
        self.user_node.ssh_user = self.user
        self.user_node.ssh_password = macro.COMMON_PASSWD
        self.data_path = os.path.join('/home', self.user, 'data')
        self.app_path = os.path.join('/home', self.user, 'app')
        self.libpq_path = os.path.join(self.data_path, 'libpq_data')
        self.com_install.data_path = self.data_path
        self.com_install.app_path = self.app_path

        text = '----prestep2:创建数据库用户和用户组;expect:创建成功----'
        self.log.info(text)
        self.com_install.prepare_user(self.user, self.root_node)

        text = '----prestep3:获取数据库安装包并解压;expect:成功----'
        self.log.info(text)
        res = self.com_install.tar_pkg(self.root_node)
        self.assertIn('install.sh', res, f'执行失败: {text}')

        text = '----prestep4:执行脚本安装数据库;expect:安装成功----'
        self.log.info(text)
        res = self.com_install.install_single(self.user_node, self.port)
        self.log.info(res)
        self.assertIn('start datanode success', res, f'执行失败: {text}')

        text = '----prestep5:创建数据库用户;expect:创建成功----'
        self.log.info(text)
        sql_cmd = f'create user {self.com_user} password' \
                  f' \'{macro.COMMON_PASSWD}\';' \
                  f'grant all privileges to {self.com_user};'
        exe_cmd = f'gsql -d postgres -p {self.port} -c "{sql_cmd}"'
        self.log.info(exe_cmd)
        exe_msg = self.user_node.sh(exe_cmd).result()
        self.log.info(exe_msg)
        self.assertIn(self.constant.CREATE_ROLE_SUCCESS_MSG, exe_msg,
                      text + '执行失败')

        text = '----prestep6:配置白名单文件;expect:配置成功----'
        self.log.info(text)
        config = f'host all {self.com_user} {self.user_node.ssh_host}/32 sha256'
        exe_cmd = f'gs_guc reload -D {self.data_path} -h "{config}"'
        self.log.info(exe_cmd)
        exe_msg = self.user_node.sh(exe_cmd).result()
        self.log.info(exe_msg)
        self.assertIn('Success to perform gs_guc', exe_msg, text + '执行失败')

        text = '------step1:解压libpq压缩包;expect:成功------'
        self.log.info(text)
        ls_cmd = f'ls {self.pkg_path} |grep -i "Lite-Libpq"'
        libpq_tar = self.user_node.sh(ls_cmd).result()
        self.log.info(libpq_tar)
        self.common.scp_file(self.user_node,
                             f"{self.params_file}.c", self.libpq_path)
        cmd1 = f'cp {os.path.join(self.pkg_path, libpq_tar)}' \
               f' {self.libpq_path};' \
               f'tar -zxf {os.path.join(self.libpq_path, libpq_tar)} -C' \
               f' {self.libpq_path};' \
               f'chmod -R 777 {self.libpq_path}'
        self.log.info(cmd1)
        res1 = self.root_node.sh(cmd1).result()
        self.log.info(res1)
        self.assertEqual('', res1, text + '执行失败')
        
        text = '---step2:连接数据库的相关信息写入文件;expect:成功---'
        self.log.info(text)
        file_cont = ['localhost', 'db_port', 'db_name', 'db_user', 'user_passwd']
        replace_cont = [self.user_node.ssh_host, self.port, 'testdb',
                        self.com_user, self.user_node.ssh_password]
        for file_item, replace_item in zip(file_cont, replace_cont):
            cmd2_2 = f'sed -i "s/{file_item}/{replace_item}/g" ' \
                     f'{os.path.join(self.libpq_path, self.params_file)}.c'
            self.log.info(cmd2_2)
            res2_2 = self.user_node.sh(cmd2_2).result()
            self.assertEqual('', res2_2, text + '执行失败')
        cmd2_3 = f'cat {os.path.join(self.libpq_path, self.params_file)}.c'
        res2_3 = self.user_node.sh(cmd2_3).result()
        self.log.info(res2_3)
        self.assertIn(self.user_node.db_host, res2_3, text + '执行失败')

        text = '---step3:编译脚本;expect:成功---'
        self.log.info(text)
        cmd3 = f"gcc -c '{os.path.join(self.libpq_path, self.params_file)}.c'" \
               f" -o '{os.path.join(self.libpq_path, self.params_file)}.o'; " \
            f"gcc -o {os.path.join(self.libpq_path, self.params_file)} " \
            f"{os.path.join(self.libpq_path, self.params_file)}.o " \
            f"{os.path.join(self.libpq_path, 'lib', 'libpq.so')};"
        self.log.info(cmd3)
        res3 = self.user_node.sh(cmd3).result()
        self.log.info(res3)
        self.assertIn('', res3, text + '执行失败')
        
        text = '---step4:执行脚本，连接不存在的数据库;expect:连接失败---'
        self.log.info(text)
        cmd4 = f'/./{os.path.join(self.libpq_path, self.params_file)}'
        self.log.info(cmd4)
        res4 = self.user_node.sh(cmd4).result()
        self.log.info(res4)
        self.assertIn('database "TESTDB" does not exist', res4, '执行失败' + text)
    
    def tearDown(self):
        text = '---step1.清理环境;expect:成功---'
        self.log.info(text)
        res = self.com_uninstall.uninstall(self.user_node)
        self.com_uninstall.clear_env(self.root_node)
        self.assertIn('success', res, f'执行失败: {text}')
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
